﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using TinyPMS_Jerusalem.Models.DBModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using TinyPMS_Jerusalem.Models.Interface;
using TinyPMS_Jerusalem.Exceptions;

namespace TinyPMS_Jerusalem.Models
{
    #region Services

    #endregion

    #region Models
    public class PropertyDBModel : Repository<Property>, IPropertyReposity
    {
        public PropertyDBModel(System.Data.Linq.DataContext context)
            : base(context)
        {
        }
        
        public void Borrow(Property instance,string userName)
        {
            if (instance.Available == false)
            {
                throw new PermissionDeniedException("物品不提供借出，您无法借出此物品");
            }
            else
            {
                if (instance.Status == true)
                {
                    throw new PermissionDeniedException("物品已经被借出，您无法借出此物品");
                }
                else
                {
                    DBModelDataContext context=new DBModelDataContext();
                    Repository<BorrowLog> borrowLogRepository = new Repository<BorrowLog>(context);
                    DBModel.BorrowLog borrowLog = new BorrowLog();
                    borrowLog.ApplyTime = DateTime.Now;
                    borrowLog.PropertyID = instance.ID;
                    borrowLog.UserName = userName;
                    borrowLogRepository.Add(borrowLog);
                    borrowLogRepository.Save();
                }
            }
        }

        public void Return(Property instance,string userName)
        {
            instance.Status = false;
            instance.BorrowerName = null;
            instance.RenewCount = 0;
            Repository<BorrowLog> borrowLogRepository = new Repository<BorrowLog>(new DBModelDataContext());
            List<BorrowLog> logList=borrowLogRepository.GetAll(c => c.PropertyID == instance.ID && c.IsApproved == true && c.UserName == userName && c.ReturnTime == null).ToList();
            if (logList.Count <= 0)
                throw new ArgumentException("发生未知错误");
            else
            {
                BorrowLog log = logList.Single();
                log.ReturnTime = DateTime.Now;
                borrowLogRepository.Save();
            }
        }

        public void Renew(Property instance,string userName)
        {
            DBModelDataContext context = new DBModelDataContext();
            Repository<RenewLog> renewLogRepository = new Repository<RenewLog>(context);
            Repository<BorrowLog> borrowLogRepository = new Repository<BorrowLog>(context);
            RenewLog renewLog = new RenewLog();
            renewLog.PropertyID = instance.ID;
            renewLog.Time = DateTime.Now;
            renewLog.UserName = userName;
            renewLogRepository.Add(renewLog);
            renewLogRepository.Save();
            BorrowLog borrowLog = borrowLogRepository.GetAll(c => c.PropertyID == instance.ID && c.UserName == userName && c.ReturnTime == null&&c.IsApproved==true).ToList().Single();
            borrowLog.DueTime.Value.AddDays(instance.Duration);
            borrowLogRepository.Save();
        }

        public override void Add(Property instance)
        {
            throw new NotImplementedException("非法访问操作");
        }

        public override void Delete(Property instance)
        {
            throw new NotImplementedException("非法访问操作");
        }

        public List<Property> Search(string keywords)
        {
            string[] keywordArray=keywords.Split(' ');
            return this.GetAll(c => Contains(c.ID, keywordArray) || Contains(c.Name, keywordArray) || Contains(c.Introduction, keywordArray) || Contains(c.Category, keywordArray) || Contains(c.Tags, keywordArray)).ToList();
        }

        private bool Contains(string textToSearch, string[] keywords)
        {
            bool flag=false;
            foreach (string keyword in keywords)
            {
                if (textToSearch.Contains(keyword))
                {
                    flag = true;
                    break;
                }
            }
            return flag;
        }
    }

    public class PropertyDetailDBModel : Interface.IPropertyDetail
    {
        DBModel.DBModelDataContext context = new DBModelDataContext();
        public PropertyDetailDBModel()
        {
        }

        public object GetDetail(string propertyID)
        {
            var query = from g in context.DetailType
                        where g.PropertyID == propertyID
                        select g;
            if (query.Count() != 1)
                return null;
            else
            {
                object result = null; ;
                var newQuery = context.GetTable(Type.GetType("TinyPMS_Jerusalem.Models.DBModel." + query.Single().Type));
                foreach (var obj in newQuery)
                {
                    Type type = obj.GetType();
                    string str;
                    str = type.InvokeMember("PropertyID", System.Reflection.BindingFlags.GetProperty, null, obj, null).ToString();
                    if (str == propertyID)
                    {
                        result = obj;
                        break;
                    }
                }
                return result;
            }
        }
    }

    public class PropertyAdminDBModel:Repository<Property>,IPropertyAdminRepository
    {
        public PropertyAdminDBModel(DBModelDataContext context):base(context)
        {

        }

        public void ApproveBorrowApply(BorrowLog instance,string adminName)
        {
            if (instance.IsApproved == true)
            {
                throw new ArgumentException("物品借出申请已经被审核通过");
            }
            else
            {
                //添加新的AdminActionLog对象
                Repository<AdminActionLog> adminLogRepository = new Repository<AdminActionLog>(context);
                AdminActionLog adminLog = new AdminActionLog();
                adminLog.AdminName = adminName;
                adminLog.Time = DateTime.Now;
                adminLog.Remark = string.Format("通过用户{0}借出物品ID为{1}的物品的申请", instance.UserName, instance.PropertyID);
                adminLog.Type = "ApproveBorrowApply";
                adminLogRepository.Add(adminLog);
                //修改各个对象的属性实现通过借出申请这一行为
                instance.BorrowTime = DateTime.Now;
                PropertyDBModel propertyDBModel = new PropertyDBModel(context);
                Property property = propertyDBModel.GetElementByID(instance.PropertyID);
                property.BorrowerName = instance.UserName;
                property.Status = true;
                instance.DueTime = DateTime.Now.AddDays(property.Duration);
                instance.IsApproved = true;
            }
        }

        public void CreateViewDataForDropLists(out List<SelectListItem> categoryListViewData, out List<SelectListItem> availableListViewData)
        {
            Repository<PropertyCategory> categoryRepository = new Repository<PropertyCategory>(new DBModelDataContext());
            List<SelectListItem> categoryList = new List<SelectListItem>();
            List<PropertyCategory> categories=categoryRepository.GetAll().ToList();
            foreach (PropertyCategory category in categories)
            {
                categoryList.Add(new SelectListItem { Text=category.Name, Value = category.Name,Selected=false });
            }
            categoryListViewData = categoryList;
            List<SelectListItem> availableList = new List<SelectListItem>();
            availableList.Add(new SelectListItem { Text = "提供借出", Value = "True" });
            availableList.Add(new SelectListItem { Text = "不提供借出", Value = "False" });
            availableListViewData = availableList;
            categoryListViewData[0].Selected = true;
            availableListViewData[0].Selected = true;
        }
    }
    #endregion

    //Todo(JZZ):统一Repository类的Save()方法调用的时间


}
